const state = {
  visitedViews: [],
  cachedViews: []
}

/**
 * 对比是不是存在同一个标签,
 * tagetRouter 要跳转的路由
 * current 当前对比参照的或已经存在的路由的其中一个
 * 返回值 result :true标识存在相同的路由
 */
const theSamePage = function(tagetRouter = {}, current = {}) {
  const filterArr = ['Edit', 'Item']
  // 是否包含指定的页面
  const isMulti = filterArr.some(i => tagetRouter.path.endsWith(i))
  // 路由是否已经存在
  const eXistence = current.path === tagetRouter.path
  // 同路由的标识字段值是否一样
  let theSame = false
  const query = tagetRouter.query || {}
  if (query.PK_FIELD && current.query) {
    theSame = eXistence && query[query.PK_FIELD] === current.query[query.PK_FIELD]
  }
  const result = eXistence ? (isMulti ? theSame : true) : false
  return result
}
/**
 * 对比是不是要新增标签,
 * tagetRouter 要跳转的路由
 * routers 已经存在的路由数组
 */
const isNewTags = function(routers = [], tagetRouter = {}) {
  // 多标签页面过滤规则
  const filterArr = ['Edit', 'Item']
  // 路由是否已经存在
  const isEXistence = routers.some(r => r.path === tagetRouter.path)
  const title = tagetRouter.meta.title || '未命名'
  // 如果路由已经存在
  if (isEXistence) {
    // 是否是多标签页面
    const isMulti = filterArr.some(i => tagetRouter.path.endsWith(i))
    // 同路由的标识字段值是否一样
    const query = tagetRouter.query || {}
    const theSame = routers.some(r => (query.PK_FIELD && r.query) ? (tagetRouter.path === r.path && query[query.PK_FIELD] === r.query[query.PK_FIELD]) : false)
    // 如果此id不存在 添加路由
    if (isMulti && !theSame) {
      state.visitedViews.push({ ...tagetRouter, title })
    }
    return
  }
  // 添加路由
  state.visitedViews.push({ ...tagetRouter, title })
}

/**
 * 对比是不是要新增标签,如果存在则更新路由参数
 * tagetRouter 要跳转的路由
 * routers 已经存在的路由数组
 */
const existencePage = function(routers = [], tagetRouter = {}) {
  // 多标签页面过滤规则
  const filterArr = ['Edit', 'Item']
  // 路由是否已经存在
  const eXistenceArr = routers.filter(r => r.path === tagetRouter.path)
  // 如果路由已经存在
  if (eXistenceArr.length > 0) {
    // 是否是多标签页面
    const isMulti = filterArr.some(i => tagetRouter.path.endsWith(i))
    if (!isMulti) {
      Object.assign(eXistenceArr[0], tagetRouter)
      return
    }
    // 同路由的标识字段值是否一样
    const theSame = eXistenceArr.filter(r => {
      if (tagetRouter.PK_FIELD && tagetRouter.path === r.path && tagetRouter[tagetRouter.PK_FIELD] === r[tagetRouter.PK_FIELD]) {
        return r
      }
    })
    if (isMulti && theSame.length > 0) {
      Object.assign(theSame[0], tagetRouter)
    }
  }
}

const mutations = {
  ADD_VISITED_VIEW: (state, view) => {
    isNewTags(state.visitedViews, view)
  },
  ADD_CACHED_VIEW: (state, view) => {
    if (state.cachedViews.includes(view.name)) return
    if (!view.meta.noCache) {
      state.cachedViews.push(view.name)
    }
  },

  DEL_VISITED_VIEW: (state, view) => {
    sessionStorage.removeItem(view.name)
    let count = 0
    for (const [i, v] of state.visitedViews.entries()) {
      count++
      if (theSamePage(view, v)) {
        state.visitedViews.splice(i, 1)
        break
      }
    }
    if (count === 0 && state.visitedViews.length === 2) {
      state.visitedViews.splice(1, 1)
    }
  },
  DEL_CACHED_VIEW: (state, view) => {
    sessionStorage.removeItem(view.name)
    for (const i of state.cachedViews) {
      if (i === view.name) {
        const index = state.cachedViews.indexOf(i)
        state.cachedViews.splice(index, 1)
        break
      }
    }
  },

  DEL_OTHERS_VISITED_VIEWS: (state, view) => {
    const sessionKeys = Object.keys(sessionStorage)
    for (let i = 0; i < sessionKeys.length; i++) {
      if (sessionKeys[i] !== view.name) {
        sessionStorage.removeItem(sessionKeys[i])
      }
    }
    state.visitedViews = state.visitedViews.filter(v => {
      return v.meta.affix || v.fullPath === view.fullPath
    })
  },
  DEL_OTHERS_CACHED_VIEWS: (state, view) => {
    const sessionKeys = Object.keys(sessionStorage)
    for (let i = 0; i < sessionKeys.length; i++) {
      if (sessionKeys[i] !== view.name) {
        sessionStorage.removeItem(sessionKeys[i])
      }
    }
    for (const i of state.cachedViews) {
      if (i === view.name) {
        const index = state.cachedViews.indexOf(i)
        state.cachedViews = state.cachedViews.slice(index, index + 1)
        break
      }
    }
  },

  DEL_ALL_VISITED_VIEWS: state => {
    sessionStorage.clear()
    // keep affix tags
    const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
    state.visitedViews = affixTags
  },
  DEL_ALL_CACHED_VIEWS: state => {
    sessionStorage.clear()
    state.cachedViews = []
  },

  UPDATE_VISITED_VIEW: (state, view) => {
    existencePage(state.visitedViews, view)
  }
}

const actions = {
  addView({ dispatch }, view) {
    dispatch('addVisitedView', view)
    dispatch('addCachedView', view)
  },
  addVisitedView({ commit }, view) {
    commit('ADD_VISITED_VIEW', view)
  },
  addCachedView({ commit }, view) {
    commit('ADD_CACHED_VIEW', view)
  },

  delView({ dispatch, state }, view) {
    return new Promise(resolve => {
      dispatch('delVisitedView', view)
      dispatch('delCachedView', view)
      resolve({
        visitedViews: [...state.visitedViews],
        cachedViews: [...state.cachedViews]
      })
    })
  },
  delVisitedView({ commit, state }, view) {
    return new Promise(resolve => {
      commit('DEL_VISITED_VIEW', view)
      resolve([...state.visitedViews])
    })
  },
  delCachedView({ commit, state }, view) {
    return new Promise(resolve => {
      commit('DEL_CACHED_VIEW', view)
      resolve([...state.cachedViews])
    })
  },

  delOthersViews({ dispatch, state }, view) {
    return new Promise(resolve => {
      dispatch('delOthersVisitedViews', view)
      dispatch('delOthersCachedViews', view)
      resolve({
        visitedViews: [...state.visitedViews],
        cachedViews: [...state.cachedViews]
      })
    })
  },
  delOthersVisitedViews({ commit, state }, view) {
    return new Promise(resolve => {
      commit('DEL_OTHERS_VISITED_VIEWS', view)
      resolve([...state.visitedViews])
    })
  },
  delOthersCachedViews({ commit, state }, view) {
    return new Promise(resolve => {
      commit('DEL_OTHERS_CACHED_VIEWS', view)
      resolve([...state.cachedViews])
    })
  },

  delAllViews({ dispatch, state }, view) {
    return new Promise(resolve => {
      dispatch('delAllVisitedViews', view)
      dispatch('delAllCachedViews', view)
      resolve({
        visitedViews: [...state.visitedViews],
        cachedViews: [...state.cachedViews]
      })
    })
  },
  delAllVisitedViews({ commit, state }) {
    return new Promise(resolve => {
      commit('DEL_ALL_VISITED_VIEWS')
      resolve([...state.visitedViews])
    })
  },
  delAllCachedViews({ commit, state }) {
    return new Promise(resolve => {
      commit('DEL_ALL_CACHED_VIEWS')
      resolve([...state.cachedViews])
    })
  },

  updateVisitedView({ commit }, view) {
    commit('UPDATE_VISITED_VIEW', view)
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
